const Api = require('co-wechat-api');

const api = Symbol('weixin-api');

module.exports = appProto => {

    Object.defineProperty(appProto, 'weixinApi', {

        get() {
            if (!this[api]) {
                const config = this.config;

                if (!config.weixin || !config.weixin.webUrl || !config.weixin.appId || !config.weixin.appSecret) {
                    throw new Error('weixin.webUrl, weixin.appId and weixin.appSecret is required in config');
                }

                let webUrl = config.weixin.webUrl;
                if (webUrl[webUrl.length - 1] === '/') {
                    webUrl = webUrl.substr(0, webUrl.length - 1);
                }

                const client = new Api(config.weixin.appId, config.weixin.appSecret,
                    async () => {
                        const r = await this.api.clients.get('bind').getToken(`token/${config.weixin.appId}`);
                        this.logger.info("get weixin api token", r);
                        return r;
                    },
                    async token => {
                        this.logger.info("set weixin api token", token);
                        await this.api.clients.get('bind').setToken(`token/${config.weixin.appId}`, token);
                    }
                );

                client.registerTicketHandle(
                    async type => {
                        const r = await this.api.clients.get('bind').getToken(`${type}/${config.weixin.appId}`);
                        this.logger.info("get weixin ticket", type, r);
                        return r;
                    },
                    async (type, ticket) => {
                        this.logger.info("set weixin ticket", ticket);
                        await this.api.clients.get('bind').setToken(`${type}/${config.weixin.appId}`, ticket);
                    }
                );

                const oldGetJsConfig = client.getJsConfig;
                client.getJsConfig = (opts) => {
                    const nopts = Object.assign({}, opts, {
                        url: `${webUrl}${opts.url}`
                    });
                    this.logger.info('js api', nopts);
                    return oldGetJsConfig.call(client, nopts);
                }

                this[api] = client;
            }
            return this[api];
        }
    });
}
